/*
 * Copyright (c) 2006-2025, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-30     AI Assistant UART5 driver with DMA
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "uart5.h"

#define SAMPLE_UART_NAME       "uart5"

/* 用于接收消息的信号量 */
static struct rt_semaphore rx_sem;
rt_device_t serial;

/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

/* 接收线程入口函数 */
static void serial_thread_entry(void *parameter)
{
    char ch;

    while (1)
    {
        /* 从串口读取一个字节 */
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }

        /* 将接收到的数据回显 */
        rt_device_write(serial, 0, &ch, 1);
    }
}

/**
 * @brief UART5 初始化函数
 *
 * @return int RT_EOK(0) 表示成功，其他值表示错误
 */
static int uart5_init(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "UART5 initialized!\r\n";

    // 使用默认串口名称
    rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);

    /* 查找串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("[UART5] Device %s not found!\n", uart_name);
        return -RT_ERROR;
    }

    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    /* 打开设备 */
    if (rt_device_open(serial, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
    {
        rt_kprintf("[UART5] Open device failed!\n");
        return -RT_ERROR;
    }

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);

    /* 发送初始化消息 */
    rt_device_write(serial, 0, str, rt_strlen(str));
    rt_kprintf("[UART5] Initialized and test message sent\n");

    /* 创建接收线程 */
    rt_thread_t thread = rt_thread_create("uart5_rx",
                                         serial_thread_entry,
                                         RT_NULL,
                                         1024,
                                         25,
                                         10);

    /* 启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        rt_kprintf("[UART5] Thread create failed!\n");
        ret = -RT_ERROR;
    }

    return ret;
}

/* 使用设备级初始化 */
INIT_DEVICE_EXPORT(uart5_init);

/**
 * @brief 发送数据到UART5
 *
 * @param data 要发送的数据指针
 * @param size 数据大小
 */
void uart5_send(const void *data, rt_size_t size)
{
    if (serial && rt_device_write(serial, 0, data, size) != size)
    {
        rt_kprintf("[UART5] Send failed\n");
    }
}
